<template>
  <el-form ref="ruleFormRef" :model="ruleForm" :rules="rules" label-width="70">
    <el-form-item label="账号" prop="username">
      <el-input v-model="ruleForm.username" placeholder="请输入账号" />
    </el-form-item>
    <el-form-item label="密码" prop="password">
      <el-input
        type="password"
        v-model="ruleForm.password"
        autocomplete="true"
        placeholder="请输入密码"
        show-password
      />
    </el-form-item>
  </el-form>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import { useUserStore } from '@/store/userStore'
import { useRouter } from 'vue-router'
import { Md5 } from 'ts-md5'
import { MyStorage } from '@/utils/utils'
import type { FormInstance, FormRules } from 'element-plus'
const emit = defineEmits(['handleLoading'])
const userStore = useUserStore()
const router = useRouter()

const usernameStorageType = 'username'
const passwordStorageType = 'password'

const ruleFormRef = ref<FormInstance>()
const ruleForm = reactive({
  username: MyStorage.get(usernameStorageType) ?? '',
  password: MyStorage.get(passwordStorageType) ?? ''
})
// 相关表单项的校验信息
const validatorUserName = (rule: any, value: any, callback: any) => {
  if (value.length === 0) {
    callback(new Error('请输入账号!'))
  } else if (value.length < 3) {
    callback(new Error('账号长度不能小于3位'))
  } else {
    callback()
  }
}
const validatorPassword = (rule: any, value: any, callback: any) => {
  if (value.length === 0) {
    callback(new Error('请输入密码!'))
  } else if (value.length < 6) {
    callback(new Error('密码长度不能小于6位'))
  }
  // else if (!/^(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).+$/.test(value)) {
  //   callback(new Error('密码必须包含大小写字母和数字!'))
  // }
  else {
    callback()
  }
}

// 定义表单规则
const rules = reactive<FormRules<typeof ruleForm>>({
  username: [{ required: true, validator: validatorUserName, trigger: 'blur' }],
  password: [{ required: true, validator: validatorPassword, trigger: 'blur' }]
})

// 定义校验函数，应该按钮在父组件，而需要校验的信息在子组件中，因此需要再子组件中暴露方法
const verifyAccount = (checkValue: boolean) => {
  ruleFormRef.value?.validate(async (val) => {
    if (val) {
      try {
        emit('handleLoading', true)
        // 发送登录请求
        const username = ruleForm.username
        const password = ruleForm.password
        const md5 = new Md5()
        let md5pasw = md5.appendAsciiStr(password).end() //加密后的md5密码

        // 调用pinia中的登录请求
        interface Res {
          code: number
          message: string
        }
        // @ts-ignore
        let res: Res | undefined = await userStore.loginAction({ username, md5pasw })
        if (res?.code !== 200) {
          throw new Error(res?.message)
        }
        // 根据checkValue的值判断是否本地存储用户登录账号和密码
        if (checkValue) {
          // 不需要重复保存
          if (!MyStorage.get('username') && !MyStorage.get('password')) {
            MyStorage.set(usernameStorageType, username)
            MyStorage.set(passwordStorageType, password)
          }
        } else {
          if (MyStorage.get('username') && MyStorage.get('password')) {
            // 如果没有勾选记住密码，就将本地数据清除
            MyStorage.remove(usernameStorageType)
            MyStorage.remove(passwordStorageType)
          }
        }
        ElMessage({
          message: res.message,
          type: 'success'
        })

        // 路由跳转
        router.push('/main')
        emit('handleLoading', false)
      } catch (error) {
        console.log('用户登录失败', error)
        ruleFormRef.value?.resetFields()
        emit('handleLoading', false)
      }
      return
    } else {
      //ElMessage配置了按需引入，因此不能再次导入
      ElMessage({
        message: '请重新输入！',
        type: 'warning'
      })
      Object.assign(ruleForm, { username: '', password: '' })
    }
  })
}
// 导出自身方法，可以通过组件实例获取
defineExpose({ verifyAccount })
</script>

<style lang="scss" scoped></style>
